<template>
  <div class="upCopperCont">
    <div class="formVal headImg" :key="index" v-for="(item, index) in imgArr">
      <img :src="item.img" />
      <div
        @click="delImgFn(index)"
        class="delIcon iconfont icon-shanchu11"
      ></div>
    </div>
    <div class="formVal headImg">
      <div class="upImg">
        <div class="upload-inner">
          <div class="iconfont icon-shangchuan1 upload-icon"></div>
          <div class="upText">{{ text }}</div>
        </div>
      </div>
      <input ref="file" type="file" @change="onFileChange($event)" />
    </div>
    <cool-dialog
      v-model="dialogVisible"
      title="图片裁剪"
      :closeOnClickModal="true"
      @confirm="onUpdatePhoto"
      @cancel="cancelFn"
    >
      <div class="preview-image-wrap">
        <img
          ref="preview-image"
          class="preview-image"
          :src="previewImage"
          alt=""
        />
      </div>
    </cool-dialog>
  </div>
</template>

<script>
import "cropperjs/dist/cropper.css";
import Cropper from "cropperjs";
import { uploadFile } from "@/http/upfile.js";
import { ElMessage, ElMessageBox, ElLoading } from "element-plus";
import CoolDialog from "@/components/CoolDialog.vue";

export default {
  components: { CoolDialog },
  data () {
    return {
      previewImage: "",
      dialogVisible: false,
      headImg: "",
      imgArr: this.propImg,
    };
  },
  props: {
    propImg: {
      default: [],
    },
    text: { default: "图片上传" },
  },
  methods: {
    emitFn () {
      let src = "";
      if (this.imgArr.length > 0) {
        let arr = this.imgArr.map((item) => {
          return item.img;
        });
        src = arr.join(",");
      }
      this.$emit("ok", src);
    },
    delImgFn (index) {
      this.imgArr.splice(index, 1);
      this.emitFn();
    },
    cancelFn () {
      this.dialogVisible = false;
      if (this.cropper) {
        this.cropper.destroy();
      }
      this.previewImage = "";
      this.$refs.file.value = "";
    },
    onFileChange (e) {
      let file = e.target.files[0];
      let blobData = window.URL.createObjectURL(file);
      this.previewImage = blobData;
      this.dialogVisible = true;
      // 解决选择相同图片不触发change事件的问题
      this.$refs.file.value = "";
    },

    onUpdatePhoto () {
      if (!this.upImgLoad) {
        this.cropper.getCroppedCanvas().toBlob(async (file) => {
          const loading = ElLoading.service({
            lock: true,
            text: "Loading",
            background: "rgba(255, 255, 255, 0.7)",
          });
          try {
            let { src } = await uploadFile(file);
            if (src) {
              this.imgArr.push({ img: src });
              this.emitFn();
              this.previewImage = src;
              this.dialogVisible = false;
              this.cropper.destroy();
            } else {
              ElMessage({
                type: "error",
                message: "裁剪失败",
              });
            }
          } catch {
            ElMessage({
              type: "error",
              message: "服务异常",
            });
          }
          loading.close();
        });
      }
    },

    onDialogOpened () {
      this.$nextTick(() => {
        let image = this.$refs["preview-image"];
        if (image) {
          let cropper = new Cropper(image, {
            aspectRatio: 1 / 1, // 裁剪框比列  1/1 长与宽的比列  NaN:任意比列
            viewMode: 1, // 0:对裁剪框的移动没有限制  1:裁剪框不能超过图片//2:裁剪框不能超过图片且图片高度和阴影背景高度一样  3:让图片完全填充阴影背景
            dragMode: "none",
            zoomOnTouch: true, //是否可以通过触摸的形式来去放大图片(手机端)
            zoomable: true, //是否允许缩放图片
            autoCropArea: 0.8, //当初始化时，裁剪框的大小与原图的比例
            background: true, //是否显示网格背景
            center: true, //裁剪框是否在图片的中心
            cropBoxResizable: true, //是否可以调节裁剪框的大小
          });
          this.cropper = cropper;
        }
      });
    },
  },
  watch: {
    dialogVisible (val) {
      if (val) {
        this.onDialogOpened();
      }
    },
  },
  mounted () {},
  created () {},
};
</script>

<style scoped lang="less">
.upCopperCont {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  .headImg {
    width: 100px;
    margin-right: 20px;
    cursor: pointer;
    height: 100px;
    border-radius: 12px;
    background: linear-gradient(145deg, #f6f8fc, #e8ecf5);
    border: none;
    transition: all 0.3s ease;
    position: relative;
    overflow: hidden;
    margin-bottom: 20px;
    box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.05),
      -5px -5px 10px rgba(255, 255, 255, 0.8);

    &:hover {
      box-shadow: 7px 7px 15px rgba(0, 0, 0, 0.08),
        -7px -7px 15px rgba(255, 255, 255, 0.9);
      transform: translateY(-2px);

      .upImg {
        .upload-inner {
          .upload-icon {
            color: #4b58dc;
            transform: scale(1.1) rotate(10deg);
            text-shadow: 0 0 10px rgba(64, 158, 255, 0.4);
          }

          .upText {
            color: #4b58dc;
            font-weight: normal;
            font-size: 13px;
          }

          &:after {
            transform: translate(-50%, -50%) scale(1.2);
            opacity: 0.3;
          }
        }
      }
    }

    &:active {
      box-shadow: inset 3px 3px 6px rgba(0, 0, 0, 0.08),
        inset -3px -3px 6px rgba(255, 255, 255, 0.8);
      transform: translateY(0);
    }

    .delIcon {
      position: absolute;
      top: 0;
      right: 0;
      font-size: 14px;
      color: #fff;
      width: 26px;
      height: 26px;
      background: linear-gradient(135deg, #f56c6c, #f78989);
      text-align: center;
      line-height: 26px;
      border-radius: 0px 10px 0 10px;
      z-index: 2;
      transition: all 0.3s ease;
      box-shadow: -2px -2px 5px rgba(0, 0, 0, 0.1);

      &:hover {
        background: linear-gradient(135deg, #f78989, #f56c6c);
        transform: scale(1.05);
      }
    }

    input {
      width: 100%;
      height: 100%;
      cursor: pointer;
      opacity: 0;
      position: absolute;
      top: 0;
      left: 0;
      z-index: 10;
    }

    .upImg {
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;

      .upload-inner {
        text-align: center;
        position: relative;

        &:after {
          content: "";
          position: absolute;
          top: 50%;
          left: 50%;
          width: 80px;
          height: 80px;
          border-radius: 50%;
          background: radial-gradient(
            circle,
            rgba(64, 158, 255, 0.2) 0%,
            transparent 70%
          );
          transform: translate(-50%, -50%);
          z-index: -1;
          transition: all 0.5s ease;
          opacity: 0.2;
        }

        .upload-icon {
          font-size: 30px;
          color: #8c9cb8;
          transition: all 0.3s ease;
        }

        .upText {
          margin-top: 8px;
          font-weight: normal;
          font-size: 13px;
          color: #8c9cb8;
          transition: all 0.3s ease;
        }
      }
    }

    img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      border-radius: 12px;
      transition: all 0.3s ease;
    }
  }
}

.preview-image-wrap {
  width: 100%;
  background-color: #f5f7fa;
  height: 400px;
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;

  .preview-image {
    display: block;
    max-width: 100%;
    max-height: 100%;
  }
}
</style>
